--- title: "03-接口多实现" created: 2025-12-02 tags: - Java --- # 接口多实现 尽管 Java 不支持类的多重继承,但 Java 提供了接口的多实现机制,使得类可以实现多个接口。这允许类通过实现多个接口,获得来自多个类的功能,而不会引发多继承的歧义问题。 **Java 接口为什么可以多实现?** - 在 Java 中,接口允许多实现,这与类的多继承不同。接口本质上是为了定义类的行为规范,而不关心具体的实现。 - **Java 8 之前**,接口只能定义方法签名,不能提供方法的具体实现。因此,多个接口的实现类可以自由地选择实现哪些方法,而不会发生冲突。例如,子类只需要实现多个接口中的方法,而没有多个父类的同名方法问题。 #### **Java 8 之后的变化:接口也可以有默认方法(default method)** Java 8 引入了接口的 **默认方法**,使得接口不仅能定义方法签名,还能提供默认的实现。这时,如果一个类实现了多个接口,而这些接口有相同的默认方法,就可能出现多继承的菱形问题。 ##### **解决方案:** - **Java 强制要求**:如果一个类实现了多个接口,并且这些接口中有相同的默认方法,那么子类必须重写这个方法,明确指定具体的实现,避免歧义。 - 如果类没有重写这个方法,编译器会报错,要求类提供一个明确的实现。 #### **示例代码:** ```java interface A { default void display() { System.out.println("A's display"); } } interface B { default void display() { System.out.println("B's display"); } } class C implements A, B { // 必须重写 display 方法来解决冲突 @Override public void display() { System.out.println("C's display"); } } public class Main { public static void main(String[] args) { C obj = new C(); obj.display(); // 输出 "C's display" } } ``` 在上面的例子中,`A` 和 `B` 接口都提供了 `display()` 方法的默认实现,而 `C` 类实现了这两个接口。在这种情况下,`C` 类必须重写 `display()` 方法,编译器不会默认选择 `A` 或 `B` 中的实现,而是强制要求 `C` 提供一个明确的实现。 Java 允许一个类实现多个接口,这有助于代码复用和模块化设计。即使 Java 8 引入了接口的默认方法,仍然要求子类明确处理多个接口的冲突,避免了多继承带来的歧义问题。 通过接口的多实现,Java 保留了多继承的优势(如灵活性和代码复用),同时避免了多继承中的问题(如歧义和复杂性)。 ## 补充:重写时还能"借用"某一方的实现 被强制重写后,如果既想加入自己的逻辑,又想复用某个接口的默认实现,可以用 `接口名.super.方法名()` 显式指定: ```java class C implements A, B { @Override public void display() { A.super.display(); // 显式借用 A 的默认实现 System.out.println("C's extra"); // 再追加自己的逻辑 } } ``` 注意写法是 `A.super.display()` 而不是 `A.display()`——default 方法属于接口实例层面,必须走这个特殊语法才能调用到。 ## 补充:default 冲突的三条裁决规则 把 Java 8 之后同名方法的冲突处理归纳一下,面试常考: | 情况 | 裁决 | | --- | --- | | 类/父类方法 vs 接口 default | **类优先**:永远赢接口的 default | | 父接口 B 继承父接口 A 且重写了 default | 子接口版本胜出(更"具体"者胜) | | 两个无关接口各有同名 default | 编译报错,实现类**必须重写**,可用 `A.super.xxx()` 显式指定 | 前两条让 JVM 能自动裁决,第三条才是真正无法裁决的菱形场景——Java 选择"逼程序员表态"而不是悄悄选一个,这正是它规避 C++ 菱形继承灾难的设计哲学(背景见 [[07-为什么Java不支持多重继承?|为什么Java不支持多重继承?]])。 --- ⬅️ [[02-引入接口与类之间的隔离|引入接口与类之间的隔离]] 🏠 [[00-Java|00-Java]] ➡️ [[04-方法重载和方法重写|方法重载和方法重写]]